package net.tv90.bfmccore.api.info;

import net.tv90.bfmccore.SlainListener;
import net.tv90.bfmccore.battlepass.Battlepass;
import net.tv90.bfmccore.battlepass.BattlepassPoint;
import org.bitterorange.flansmodslain.FlansModSlain;
import org.bukkit.Bukkit;
import org.bukkit.Statistic;
import org.bukkit.entity.Player;

import java.io.*;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

import static net.tv90.bfmccore.BFMCCore.PLUGIN_ROOT;

public class PlayerStatistic {

    public static Map<String, String> playerInfoCache = new HashMap<>();

    static {
        initPlayerStatistics();
    }

    public static int getPlayerKill(Player player) {
        return player.getStatistic(Statistic.PLAYER_KILLS);
    }

    public static int getPlayerDeath(Player player) {
        return player.getStatistic(Statistic.DEATHS);
    }

    public static float getPlayerKD(Player p) {
        float f = (float) p.getStatistic(Statistic.PLAYER_KILLS) / p.getStatistic(Statistic.DEATHS);
        return (float) (Math.round(f * 100)) / 100;
    }

    public static String getPlayerRank(Player p){
        Bukkit.getOfflinePlayers();
        String rank = FlansModSlain.rankOf(p);
        String rankIndex = String.valueOf(FlansModSlain.rankIndexOf(p));
        return rank + " (" + rankIndex + "级)";
    }

    public static String getPlayerWeaponCount(String player){
        Map<String, Integer> weaponCount = SlainListener.getAllKillCount(player);
        //根据value排序前5，如果是US或RU或CN开头跳过
        StringBuilder sb = new StringBuilder();

        weaponCount.entrySet().stream()
                .filter(e -> !e.getKey().equals("null") && !e.getKey().startsWith("US") && !e.getKey().startsWith("RU") && !e.getKey().startsWith("CN") && !e.getKey().startsWith("NoF"))
                .sorted(Map.Entry.<String, Integer> comparingByValue().reversed())
                .limit(5)
                .forEach(e -> {
                    sb.append(e.getKey()).append(" 击杀数：").append(e.getValue()).append("\n");
        });

        return sb.toString();
    }

    public static String getWeaponInfo(String player, int page, int pageSize){
        Map<String, Integer> weaponCount = SlainListener.getAllKillCount(player);
        //根据value排序并分页
        int totalPage = (int) Math.ceil(weaponCount.size() / (double) pageSize);
        StringBuilder sb = new StringBuilder(player + "的武器数据如下(" + page + "/" + totalPage + ")\n");

        weaponCount.entrySet().stream()
                .filter(e -> !e.getKey().equals("null") && !e.getKey().startsWith("NoF"))
                .sorted(Map.Entry.<String, Integer> comparingByValue().reversed())
                .skip((long) (page - 1) * pageSize)
                .limit(pageSize)
                .forEach(e -> {
                    sb.append(e.getKey()).append(" 击杀数：").append(e.getValue()).append("\n");
                });

        return sb.toString();
    }


    public static String getPlayerStatistic(String player) {
        if(playerInfoCache.containsKey(player)) {
            return playerInfoCache.get(player);
        } else {
            return savePlayerStatistic(player);
        }
    }

    public static String savePlayerStatistic(String player) {
        Player p = Bukkit.getPlayer(player);
        if(p == null) {
            return "无法查询到玩家" + player + "的信息";
        }
        StringBuilder sb = new StringBuilder("玩家 ").append(player).append(" 的统计信息如下：\n");
        sb.append("等级：").append(getPlayerRank(p)).append("\n");
        sb.append(Battlepass.queryBattlepassStatistic(p)).append("\n");
        sb.append("玩家击杀数：").append(p.getStatistic(Statistic.PLAYER_KILLS)).append("\n");
        sb.append("死亡数：").append(p.getStatistic(Statistic.DEATHS)).append("\n");
        sb.append("KD：").append(getPlayerKD(p)).append("\n");
        sb.append("武器击杀数：\n").append(getPlayerWeaponCount(player)).append("\n");
        sb.append("-- 最后更新时间 ").append(LocalDateTime.now()).append(" --\n");

        playerInfoCache.put(player, sb.toString());
        return sb.toString();
    }

    /**
     * 序列化玩家的统计数据
     */
    public static void savePlayerStatisticsToFile() {
        File file = new File(PLUGIN_ROOT, "/playerStatistics.dat");
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            try (
                    OutputStream outputStream = Files.newOutputStream(file.toPath());
                    ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)
            ) {
                objectOutputStream.writeObject(playerInfoCache);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从yaml文件中读取玩家的统计数据
     */
    public static void initPlayerStatistics() {
        File file = new File(PLUGIN_ROOT, "/playerStatistics.dat");
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            try (
                    InputStream inputStream = Files.newInputStream(file.toPath());
                    ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)
            ) {
                Object object = objectInputStream.readObject();
                playerInfoCache = (object == null) ? new HashMap<>() : (Map<String, String>) object;
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
